package com.xwj.nio.reactor;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.SocketChannel;
import java.util.Iterator;
import java.util.Scanner;

/**
 * 客户端，负责发送数据
 *
 * @author xwj
 * @date 2020/6/10
 */
public class EchoClient {
    public static void main(String[] args) throws IOException {
        // 1、获取通道
        SocketChannel sc = SocketChannel.open();
        sc.socket().connect(new InetSocketAddress("127.0.0.1", 8888));
        // 2、切换成非阻塞模式
        sc.configureBlocking(false);
        // 不断的自旋、等待连接完成，或者做一些其他的事情
        while (!sc.finishConnect()) {
        }
        System.out.println("客户端启动成功");
        //启动接受线程
        Processor processor = new Processor(sc);
        new Thread(processor).start();
    }

    static class Processor implements Runnable {
        final Selector selector;
        final SocketChannel channel;

        public Processor(SocketChannel channel) throws IOException {
            //Reactor初始化
            selector = Selector.open();
            this.channel = channel;
            this.channel.register(selector,
                    SelectionKey.OP_READ | SelectionKey.OP_WRITE);
        }

        @Override
        public void run() {
            try {
                while (!Thread.interrupted()) {
                    selector.select();
                    Iterator<SelectionKey> selectionKey = selector.selectedKeys().iterator();
                    while (selectionKey.hasNext()) {
                        SelectionKey sk = selectionKey.next();
                        if (sk.isWritable()) {
                            ByteBuffer buffer = ByteBuffer.allocate(1024);
                            Scanner scanner = new Scanner(System.in);
                            System.out.println("请输入发送内容：");
                            if (scanner.hasNext()) {
                                SocketChannel socketChannel = (SocketChannel) sk.channel();
                                String next = scanner.next();
                                buffer.put(next.getBytes());
                                // 变成读模式
                                buffer.flip();
                                socketChannel.write(buffer);
                                // 变成写模式
                                buffer.clear();
                            }
                        } else if (sk.isReadable()) {
                            ByteBuffer buffer = ByteBuffer.allocate(1024);
                            SocketChannel socketChannel = (SocketChannel) sk.channel();
                            int length = 0;
                            // 读取数据
                            while ((length = socketChannel.read(buffer)) != -1) {
                                // 变成读模式
                                buffer.flip();
                                System.out.println(new String(buffer.array(), 0, length));
                                // 变成写模式
                                buffer.clear();
                            }
                        }
                        selectionKey.remove();
                    }
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
}
